/* eslint-disable */
import "./message.js";
import "./replybody.js";
import "./sentbody.js";
import { getToken } from "@/utils/request.uts"
import {
	authtoken,
	getUnReadCount,
	getLoginUserInfo
} from "@/api"
/*CIM服务器IP*/
// const CIM_HOST = "183.214.199.64:10086";
const CIM_HOST = "172.10.1.111";
/*
 *服务端 websocket端口
 */
const CIM_URI = "ws://" + CIM_HOST + "/myws/";
const APP_VERSION = "1.0.0";
const APP_CHANNEL = "web";
const APP_PACKAGE = "com.farsunset.cim";
/*
 *特殊的消息类型，代表被服务端强制下线
 */
const ACTION_999 = "999";
const DATA_HEADER_LENGTH = 1;

const MESSAGE = 2;
const REPLY_BODY = 4;
const SENT_BODY = 3;
const PING = 1;
const PONG = 0;
const DEVICENAME = "H5";
/**
 * PONG字符串转换后
 * @type {Uint8Array}
 */
const PONG_BODY = new Uint8Array([80, 79, 78, 71]);
let socket;
let interval = null;
let manualStop = false; //为true时，代表客户端主动断开标识
let websocketState = 'reconnect'; //normal 正常  offline 客户端下线  reconnect 自动重连  error 网络连接异常 
let lastReceivedTime = 0;
let reconnectCount = 0;
window.onWebsocketStateChange = function(state) {};
window.onReplyReceived = function(e) {};
const CIMPushManager = {};
const onConnect = (CIMPushManager.connect = function() {
	console.log('开始建立连接......')
	if(socket != null && websocketState == 'normal'){
		CIMPushManager.closedClient();
	}
	let deviceId = window.localStorage.deviceId;
	if (deviceId == "" || deviceId == undefined) {
		deviceId = generateUUID();
		window.localStorage.deviceId = deviceId;
	}
	getLoginUserInfo({ jwtSSOToken: getToken() }).then((data) => {
		console.log('获得用户信息：',data);
		 if(data.code === "success" && data.body){
			 const content = JSON.parse(data.body.loginUser);
			 window.localStorage.account = content.personId;
		 }
	}).catch((error) => {});
	
	manualStop = false;
	lastReceivedTime = 0;
	socket = new WebSocket(CIM_URI);
	socket.cookieEnabled = false;
	socket.binaryType = "arraybuffer";
	socket.onopen = CIMPushManager.innerOnConnectFinished;
	socket.onmessage = CIMPushManager.innerOnMessageReceived;
	socket.onclose = CIMPushManager.innerOnConnectionClosed;
});

CIMPushManager.innerOnConnectFinished = function() {
	console.log('建立连接成功！');
	CIMPushManager.bindAccount();
};

//服务端主动关闭后重连
CIMPushManager.innerOnConnectionClosed = function(e) {
	CIMPushManager.stop();
};

CIMPushManager.innerOnMessageReceived = function(e) {
	let data = new Uint8Array(e.data);
	let type = data[0];
	let body = data.subarray(DATA_HEADER_LENGTH, data.length);
	lastReceivedTime = new Date().getTime();
	authtoken().catch((error) => {});
	getUnReadCount().then((data) => {
		let res = data.body;
		window.native.setIMMessageCount(res.unReadCount);
		window.native.setBadgeCount(res.badgeCount);
	}).catch((error) => {});

	if (type === PING) {
		console.log("receive PING");
		CIMPushManager.pong();
		return;
	}

	if (type == MESSAGE) {
		let message = proto.com.farsunset.cim.sdk.web.model.Message.deserializeBinary(
			body
		);
		onInterceptMessageReceived(message.toObject(false));
		return;
	}

	if (type == REPLY_BODY) {
		let message = proto.com.farsunset.cim.sdk.web.model.ReplyBody.deserializeBinary(
			body
		);
		/**
		 * 将proto对象转换成json对象，去除无用信息
		 */
		let reply = {};
		reply.code = message.getCode();
		reply.key = message.getKey();
		reply.message = message.getMessage();
		reply.timestamp = message.getTimestamp();
		reply.data = {};

		/**
		 * 注意，遍历map这里的参数 value在前key在后
		 */
		message.getDataMap().forEach(function(v, k) {
			reply.data[k] = v;
		});

		window.onReplyReceived(reply);
	}
};

const onbindAccount = (CIMPushManager.bindAccount = function() {
	console.log('开始绑定用户......');
	websocketState = 'normal';
	reconnectCount = 0;
	let deviceId = window.localStorage.deviceId;
	let account = window.localStorage.account;
	let token = window.localStorage.token;
	let browser = getBrowser();
	let body = new proto.com.farsunset.cim.sdk.web.model.SentBody();
	body.setKey("client_bind");
	body.setTimestamp(new Date().getTime());
	body.getDataMap().set("uid", account);
	body.getDataMap().set("channel", APP_CHANNEL);
	body.getDataMap().set("appVersion", APP_VERSION);
	body.getDataMap().set("osVersion", browser.version);
	body.getDataMap().set("packageName", APP_PACKAGE);
	body.getDataMap().set("deviceId", deviceId);
	body.getDataMap().set("deviceName", DEVICENAME);
	body.getDataMap().set("browserName", browser.name);
	body.getDataMap().set("token", token);
	CIMPushManager.sendRequest(body);
	console.log('绑定用户成功！');
	console.log('account=' + account);
});

const onMessageRead = (CIMPushManager.onMessageRead = function(sourceType, receiver) {
	let account = window.localStorage.account;
	let deviceId = window.localStorage.deviceId;
	let browser = getBrowser();
	let body = new proto.com.farsunset.cim.sdk.web.model.SentBody();
	body.setKey("client_sendmsg");
	body.setTimestamp(new Date().getTime());
	body.getDataMap().set("uid", account);
	body.getDataMap().set("channel", APP_CHANNEL);
	body.getDataMap().set("appVersion", APP_VERSION);
	body.getDataMap().set("osVersion", browser.version);
	body.getDataMap().set("packageName", APP_PACKAGE);
	body.getDataMap().set("deviceId", deviceId);
	body.getDataMap().set("deviceName", DEVICENAME);
	body.getDataMap().set("browserName", browser.name);
	body.getDataMap().set("action", "998");
	body.getDataMap().set("sourceType", sourceType);
	body.getDataMap().set("sender", account);
	body.getDataMap().set("receiver", receiver);
	CIMPushManager.sendRequest(body);
});

//客户端发起关闭连接
const closedClient = CIMPushManager.closedClient = function() {
	manualStop = true; //主动断开
	websocketState = 'offline';
	let account = window.localStorage.account;
	let deviceId = window.localStorage.deviceId;
	let browser = getBrowser();
	let body = new proto.com.farsunset.cim.sdk.web.model.SentBody();
	console.log('客户端发起关闭连接,account=', account, ',deviceId=', deviceId);
	body.setKey("client_closed");
	body.setTimestamp(new Date().getTime());
	body.getDataMap().set("uid", account);
	body.getDataMap().set("channel", APP_CHANNEL);
	body.getDataMap().set("appVersion", APP_VERSION);
	body.getDataMap().set("osVersion", browser.version);
	body.getDataMap().set("packageName", APP_PACKAGE);
	body.getDataMap().set("deviceId", deviceId);
	body.getDataMap().set("deviceName", browser.name);
	CIMPushManager.sendRequest(body);
};

//服务器连接断开,关闭连接
const onCloseClient = (CIMPushManager.stop = function() {
	let account = window.localStorage.account;
	let deviceId = window.localStorage.deviceId;
	if (websocketState != 'offline' && websocketState != 'error') {
		websocketState = 'reconnect';
	}
	if (socket) {
		socket.close();
	}
	console.log('服务器连接断开,关闭连接!account=', account, ',deviceId=', deviceId);
});

//监听连接服务器是否正常
const onListenConnect = (CIMPushManager.listenConnect = function() {
	console.log("开始监听连接......");
	if (interval != null) {
		window.clearInterval(interval);
	}
	interval = setInterval(function() {
		let currentTime = new Date().getTime();
		if (websocketState == 'normal' && lastReceivedTime != 0 && currentTime - lastReceivedTime >
			1000 * 60 * 3) {
			console.log("检测收到PING的时间超时......");
			console.log("currentTime:" + currentTime);
			console.log("lastReceivedTime:" + lastReceivedTime);
			console.log("超时时间(秒):" + (currentTime - lastReceivedTime) / 1000);
			CIMPushManager.stop();
		}
		if (websocketState == 'reconnect' || websocketState == 'error') {
			CIMPushManager.connect();
			reconnectCount++;
			if (reconnectCount > 10) {
				websocketState = 'error';
			}
		}
		window.onWebsocketStateChange(websocketState);
	}, 3000);
});

CIMPushManager.sendRequest = function(body) {
	let data = body.serializeBinary();
	let protobuf = new Uint8Array(data.length + 1);
	protobuf[0] = SENT_BODY;
	protobuf.set(data, 1);
	socket.send(protobuf);
};

CIMPushManager.pong = function() {
	let pong = new Uint8Array(PONG_BODY.byteLength + 1);
	pong[0] = PONG;
	pong.set(PONG_BODY, 1);
	socket.send(pong);
};

function onInterceptMessageReceived(message) {
	let deviceId = window.localStorage.deviceId;
	console.log('接收到消息,message=', message);
	/*
	 *  被强制下线之后，不再继续连接服务端
	 */
	if (message.action == ACTION_999) {
		//服务端发送强制下线消息，客户端发起关闭连接
		let extra = JSON.parse(message.extra);
		if (extra.deviceId == deviceId) {
			CIMPushManager.closedClient();
		}
	}
	/*
	 *收到消息后，将消息发送给页面
	 */
	if (onMessageReceived instanceof Function) {
		window.onMessageReceived(message);
	}
}

function getBrowser() {
	let explorer = window.navigator.userAgent.toLowerCase();
	if (explorer.indexOf("msie") >= 0) {
		let ver = explorer.match(/msie ([\d.]+)/)[1];
		return {
			name: "IE",
			version: ver
		};
	} else if (explorer.indexOf("firefox") >= 0) {
		let ver = explorer.match(/firefox\/([\d.]+)/)[1];
		return {
			name: "Firefox",
			version: ver
		};
	} else if (explorer.indexOf("chrome") >= 0) {
		let ver = explorer.match(/chrome\/([\d.]+)/)[1];
		return {
			name: "Chrome",
			version: ver
		};
	} else if (explorer.indexOf("opera") >= 0) {
		let ver = explorer.match(/opera.([\d.]+)/)[1];
		return {
			name: "Opera",
			version: ver
		};
	} else if (explorer.indexOf("Safari") >= 0) {
		let ver = explorer.match(/version\/([\d.]+)/)[1];
		return {
			name: "Safari",
			version: ver
		};
	}
	return {
		name: "Other",
		version: "1.0.0"
	};
}

function generateUUID() {
	let d = new Date().getTime();
	let uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(
		c
	) {
		let r = (d + Math.random() * 16) % 16 | 0;
		d = Math.floor(d / 16);
		return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
	});
	return uuid.replace(/-/g, "");
}

export {
	onConnect,
	onListenConnect,
	onbindAccount,
	onCloseClient,
	onMessageRead,
	closedClient,
	APP_CHANNEL
};